/**
 + (id<AspectToken>)aspect_hookSelector:(SEL)selector
 withOptions:(AspectOptions)options
 usingBlock:(id)block
 error:(NSError **)error;
 1、aspect_hookSelector:表示要拦截指定对象的方法。
 2、withOptions:是一个枚举类型，AspectPositionAfter表示viewDidLoad方法执行后会触发usingBlock:的代码。
 3、usingBlock:就是拦截事件后执行的自定义方法。我们可以在这个block里面添加我们要执行的代码。
 */
//
//  ZMLogging.m
//  AOPDemo
//
//  Created by chenzm on 2018/8/24.
//  Copyright © 2018年 chenzm. All rights reserved.
//

#import "ZMLogging.h"

@import UIKit;

@implementation ZMLogging

typedef void (^AspectHandlerBlock)(id<AspectInfo> aspectInfo);


+ (void)setupWithConfiguration:(NSDictionary *)configs{
    // 页面统计
    [UIViewController aspect_hookSelector:@selector(viewDidAppear:)
                              withOptions:AspectPositionAfter
                               usingBlock:^(id<AspectInfo> aspectInfo) {
                                   dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
                                       NSString *className = NSStringFromClass([[aspectInfo instance] class]);
                                       NSString *pageImp = configs[className][ZMLoggingPageImpression];
                                       if (pageImp) {
                                           //监听对象处理
                                           NSLog(@"%@", pageImp);
                                       }
                                   });
                               } error:NULL];
    
    // 事件处理
    for (NSString *className in configs) {
        Class clazz = NSClassFromString(className);
        NSDictionary *config = configs[className];
        if (config[ZMLoggingTrackedEvents]) {
            for (NSDictionary *event in config[ZMLoggingTrackedEvents]) {
                SEL selekor = NSSelectorFromString(event[ZMLoggingEventSelectorName]);
                AspectHandlerBlock block = event[ZMLoggingEventHandlerBlock];
                
                [clazz aspect_hookSelector:selekor
                               withOptions:AspectPositionAfter
                                usingBlock:^(id<AspectInfo> aspectInfo) {
                                    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
                                        //代码块事件处理
                                        block(aspectInfo);
                                    });
                                } error:NULL];
                
            }
        }
    }
}


@end
